import { Module, Provider } from '@nestjs/common';
import { getModelForClass, mongoose } from '@typegoose/typegoose';
import { ConfigService } from '@nestjs/config';

type ClassType = { new (...args: any[]): any };

@Module({})
/** DbModule类，用于初始化数据库连接和模型 */
export class DbModule {
  /**
   * 用于初始化数据库连接
   * @param url 数据库连接字符串
   * @returns
   */
  static forRoot(evnKey: string, options = {}) {
    // 定义一个提供者数组
    const providers: Provider[] = [
      // 提供一个DB_CONNECTION的提供者，使用mongoose.connect方法连接数据库
      {
        provide: 'DB_CONNECTION', // 提供一个名为DB_CONNECTION的依赖
        inject: [ConfigService], // 注入一个名为ConfigService的依赖
        useFactory: (configService: ConfigService) => {
          // 使用一个工厂函数来创建依赖
          const uri = configService.get<string>(evnKey, 'MONGO_URI'); // 从ConfigService中获取MONGO_URI的值
          return mongoose.connect(uri, options); // 使用mongoose连接到数据库
        }
      }
    ];
    // 返回一个模块对象，包含模块、提供者、导出和全局属性
    return {
      module: DbModule,
      providers,
      exports: providers,
      global: true
    };
  }

  /**
   * 静态方法，用于初始化数据库模型
   * @param models 模型数组
   * @returns
   */
  static forFeature(models: ClassType[]) {
    // 定义一个提供者数组
    const providers = models.map((model) => {
      // 提供一个model.name的提供者，使用getModelForClass方法获取模型
      return {
        provide: model.name,
        useFactory: () => getModelForClass(model)
      } as Provider;
    });
    // 返回一个模块对象，包含模块、提供者、导出和全局属性
    return {
      module: DbModule,
      providers,
      exports: providers,
      global: true
    };
  }
}
